<template>
  <v-card title="PROMPT" :style="{ height: '55%'}">
    <div class=" prompt-editor-container" ref="prompt"></div>
  </v-card>
  <v-card title="N PROMPT" :style="{ height: '45%'}" flex>
    <div class=" nPrompt-editor-container" ref="nPrompt"></div>
  </v-card>
</template>

<script setup>
import loader from '@monaco-editor/loader'
import {inject, onBeforeUnmount, onMounted, ref, toRaw, watch} from 'vue';
import JSZip from 'JSZip'

const file = inject('file')
const customTags = inject('customTags')
const prompt = ref({})
const promptEditor = ref({})
const nPrompt = ref({})
const nPromptEditor = ref({})
const tagsData = ref()

const autoUpdateTranslation = setInterval(updateTranslation, 1000);

// function loadTags(path) {
//   fetch(path)
//     .then(response => response.json())
//     .then(json => {
//       tagsData.value = json;
//     })
// }
function loadTags(path) {

  fetch('tags.z')
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.blob();
    })
    .then(blob => {
      // 使用 JSZip 这个库解压缩
      return JSZip.loadAsync(blob);
    })
    .then(zip => {
      // 获取 tags.json 文件
      return zip.file('tags.json').async('text');
    })
    .then(json => {
      // 转换 JSON 字符串为 JSON 对象
      tagsData.value = JSON.parse(json);

    })
    .catch(error => {
      console.error('There was a problem with the fetch operation:', error);
    });
}

const suggestionsCache = ref(null)
const matchedSuggestions = ref(null)

function updateTranslation() {
  document.querySelectorAll('span.mtk1').forEach(value => {
    const cleanContent = value.textContent.trim()
    if (value.getAttribute('data-content-after')) {
    } else {
      const tText = translation(cleanContent);
      if (tText) {
        value.setAttribute('data-content-after', tText)
      } else {
        if (tText) {
          value.setAttribute('data-content-after', cleanContent)
        }
      }
    }
  })
}

function translation(text) {

  if (text && text != '') {
    const cleanText = text.replace(String.fromCharCode(160), " ").toLowerCase().trim()


    let customTag = customTags.value[cleanText]

    if (customTag && customTag.state == 'Enable') {
      return customTag.cn;
    }


    const tag = tagsData.value[cleanText]
    // console.log(cleanText + ':' + tag)

    // for (let i = 0; i < cleanText.length; i++) {
    //   console.log(cleanText.charCodeAt(i));
    // }
    if (tag) {
      // console.log(cleanText+':'+tag)
      if (tag['cn'] && tag['cn'] != '') {
        return tag['cn']
      }
    }

    const words = cleanText.split(/[\s\(\)\[\]\{\}]+/)

    let tText = ""
    if (words.length > 1) {
      for (let word of words) {
        tText = tText + translation(word.replace(/^\W+|\W+$/g, ''))
      }
    } else {
      tText = cleanText
    }
    return tText

  }

}

function getSuggestions(textBeforeCursor) {

  console.log(new Date() + '\tbegin:' + textBeforeCursor)

  function tagToSuggestion(tag) {
    return {
      sortText: tag['en'].length.toString().padStart(4, '0'),
      label: tag['en'].toLowerCase()+'('+( + tag['type']!=''?(tag['type']+":" + (tag['cn'])) :  tag['cn'] )+')' ,
      // filterText: tag['en'].toLowerCase() + "(" + tag['type']?":" + (tag['cn']) : + tag['cn'] + ")"
      kind: monaco.languages.CompletionItemKind.Keyword,
      insertText: tag['en'].toLowerCase(),
      detail: tag['type']
    };
  }

  suggestionsCache.value = Object.keys(tagsData.value).filter(tagName => {

    let customTag = customTags.value[tagName]

    if (customTag && customTag.state == 'Enable') {
      return false;
    }


    const matched = (tagsData.value[tagName]['en'].toLowerCase() + "(" + tagsData.value[tagName]['cn'].toLowerCase() + ")").indexOf(textBeforeCursor) > -1

    return matched

  }).map(tagName => {
      const tag = tagsData.value[tagName]
      return tagToSuggestion(tag);
    }
  );

  Object.keys(customTags.value).filter(tagName => {

    const customTag = customTags.value[tagName]


    if (customTag && customTag.state == 'Disable') {
      return false;
    }

    const matched = (customTag['en'].toLowerCase() + "(" + customTag['cn'].toLowerCase() + ")").indexOf(textBeforeCursor) > -1

    return matched

  }).map(tagName => {
      const customTag = customTags.value[tagName]
      suggestionsCache.value.push(tagToSuggestion(customTag));
    }
  )




  // suggestionsCache.value.sort((a, b) => a.insertText.length - b.insertText.length);
  console.log(new Date() + '\t:end' + textBeforeCursor)
  return suggestionsCache.value;
}

onMounted(() => {

  loadTags('tags-sort-clean-name2.json')

  loader.init().then(monaco => {
    //自定义 ai tags
    monaco.languages.register({id: 'aiDrawTags'})

    //这里填写你的语言的语法规则
    monaco.languages.setMonarchTokensProvider('aiDrawTags', {
      tokenizer: {
        root: [
          [/[()]/g, 'type'],
          [/[{}]/g, 'type'],
          [/(\[|\])/g, 'string.sql'],
          [/,/g, 'tag'],
          [/:[\d\.]+/g, 'operator.sql']
        ]
      }

    })
    //配置语言的自动补全。
    monaco.languages.registerCompletionItemProvider('aiDrawTags', {
      provideCompletionItems: (model, position, context) => {
        const line = position.lineNumber;
        const column = position.column;
        const textBeforeCursor = model.getValueInRange({
          startLineNumber: line,
          startColumn: column - 1,
          endLineNumber: line,
          endColumn: column,
          wordWrapBreakBeforeCharacters: ',',
        }).toLowerCase();

        return {
          suggestions: getSuggestions(textBeforeCursor)
        };
      },

    })

    // monaco.languages.getLanguages(); 支持的所有语言在这里可以看到
    promptEditor.value = monaco.editor.create(prompt.value/*或document.getElementById('xxx')*/, {
      value: "",
      language: 'aiDrawTags', // 代码对应的语言，可查看文档
      theme: 'vs-dark',
      automaticLayout: true,
      minimap: {
        enabled: false
      },
      lineNumbers: 'off',
      fontSize: '18px',
      lineHeight: '36px',
      wordWrapBreakBeforeCharacters: ',',
      wordWrapBreakAfterCharacters: ',',
      wordWrap: 'on',
      glyphMargin: true,
      lightbulb: {
        enabled: true
      }

    })

    promptEditor.value.onDidChangeModelContent((val) => {
      //内容改变时给父组件实时返回值
      // console.log(toRaw(promptEditor.value).getValue())
      file.value.prompt = toRaw(promptEditor.value).getValue()
      // file.value.prompt = promptEditor.value.getValue()


      // updateTranslation();

    })

    nPromptEditor.value = monaco.editor.create(nPrompt.value/*或document.getElementById('xxx')*/, {
      value: "",
      language: 'aiDrawTags', // 代码对应的语言，可查看文档
      theme: 'vs-dark',
      automaticLayout: true,
      minimap: {
        enabled: false
      },
      lineNumbers: 'off',
      fontSize: '18px',
      lineHeight: '36px',
      wordWrapBreakBeforeCharacters: ',',
      wordWrapBreakAfterCharacters: ',',
      wordWrap: 'on',
      glyphMargin: true,
      lightbulb: {
        enabled: true
      }
    })


    nPromptEditor.value.onDidChangeModelContent((val) => {
      //内容改变时给父组件实时返回值
      // console.log(toRaw(nPromptEditor.value).getValue())
      file.value.nPrompt = toRaw(nPromptEditor.value).getValue()
      // file.value.prompt = promptEditor.value.getValue()
      // updateTranslation();
    })
  })
});


onBeforeUnmount(() => {
  clearInterval(autoUpdateTranslation)
  toRaw(promptEditor.value).dispose();
  toRaw(nPromptEditor.value).dispose();

});

watch(file, (n, o) => {
  if (n.id != o.id) {
    toRaw(promptEditor.value).setValue(n.prompt);
    toRaw(nPromptEditor.value).setValue(n.nPrompt);

  }
})


</script>

<style scoped>
.prompt-editor-container {
  height: calc(100% - 68px);
  width: 100%;


}

.nPrompt-editor-container {
  height: calc(100% - 68px);
  width: 100%;

}




</style>
